#!/usr/bin/env node
var fs          = require('fs');
var readline    = require('readline');
var exec        = require('child_process').exec;
var path        = require('path');
var when        = require('when');
var utils       = require('./utils');
var Generator   = require("jison/lib/jison").Generator;
var dotEvery    = 10000;



exports.TSVParser = ( function() {

    function TSVParser(params) {
        this.failures = 0;
        this.params = params;
        this.entries = {};
        this.lines = 0;
        this.unrecognisedMeta = {};
        this.grammarSpecJSONFile = path.dirname(module.filename)+"/tvs_grammar.json";
        this.dependencies = [this.grammarSpecJSONFile, module.filename];
    }

    TSVParser.prototype.parser = function() {
        var options = {type: "lalr", moduleType: "commonjs", moduleName: "jsoncheck"};
        var grammarSpecJSON = require(this.grammarSpecJSONFile);
        var code = new Generator(grammarSpecJSON, options).generate();
        var Module = module.constructor;
        var m = new Module();
        m._compile(code);
        return m.exports.parser;
    }

    TSVParser.prototype.do = function() {
        var result = when.defer();
        var self = this;
        if (!fs.existsSync(this.params.input)) {
            throw new Error("TSVParser : Input file '"+this.params.input+"' not found");
        }
        var rd = readline.createInterface({
            input: fs.createReadStream(this.params.input),
            output: process.stdout,
            terminal: false
        });

        var parser = this.parser();
        rd.on('line', function(line) {
            //console.log("********************");
            //console.log("Parsing line ["+self.lines+"] :"+line);
            try {
                var result = parser.parse(line);
                if (result) {
                    //console.log("Parsed line: "+JSON.stringify(result));
                    if (!(result.entry in self.entries)) {
                        self.entries[result.entry] = {
                            variants : {}
                        }
                    }
                    if (!self.entries[result.entry].variants[result.properties.type]) {
                        self.entries[result.entry].variants[result.properties.type] = [];
                    }
                    self.entries[result.entry].variants[result.properties.type].push(result.properties);
                }
            } catch (e) {
                self.failures++;
            }
            if (self.lines++%dotEvery == 0) {
                process.stdout.write(".");
            }
        });

        rd.on('close', function() {
            console.log("\nFinished parsing "+self.params.input+" with "+self.failures+"("+Math.round(10000*self.failures/self.lines)/100+"%) failures.");
            result.resolve(self.entries);
        });

        return result.promise;
    }

    return TSVParser;
})();

